Skip to content

Conversation

@EbinJose2002
Copy link
Contributor

  • Checks for printf calls
  • Handling of convert_* builtins and fallback
  • Generation of nan and shuffle OpExtInst

Checks for printf, convert_* fallback, nan, and shuffle built-ins
@llvmbot
Copy link
Member

llvmbot commented Aug 1, 2025

@llvm/pr-subscribers-backend-spir-v

Author: Ebin-McW (EbinJose2002)

Changes
  • Checks for printf calls
  • Handling of convert_* builtins and fallback
  • Generation of nan and shuffle OpExtInst

Full diff: https://github.com/llvm/llvm-project/pull/151662.diff

4 Files Affected:

  • (added) llvm/test/CodeGen/SPIRV/transcoding/OpenCL/convert_functions.ll (+56)
  • (added) llvm/test/CodeGen/SPIRV/transcoding/OpenCL/nan.ll (+15)
  • (added) llvm/test/CodeGen/SPIRV/transcoding/OpenCL/shuffle.ll (+23)
  • (added) llvm/test/CodeGen/SPIRV/transcoding/printf.ll (+14)
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/convert_functions.ll b/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/convert_functions.ll
new file mode 100644
index 0000000000000..13a61b08b75df
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/convert_functions.ll
@@ -0,0 +1,56 @@
+; This test checks that functions with `convert_` prefix are translated as
+; OpenCL builtins only in case they match the specification. Otherwise, we
+; expect such functions to be translated to SPIR-V FunctionCall.
+
+; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK-SPIRV: OpName %[[#Func:]] "_Z18convert_float_func"
+; CHECK-SPIRV: OpName %[[#Func1:]] "_Z20convert_uint_satfunc"
+; CHECK-SPIRV: OpName %[[#Func2:]] "_Z21convert_float_rtzfunc"
+; CHECK-SPIRV-DAG: %[[#VoidTy:]] = OpTypeVoid
+; CHECK-SPIRV-DAG: %[[#CharTy:]] = OpTypeInt 8
+; CHECK-SPIRV-DAG: %[[#FloatTy:]] = OpTypeFloat 32
+
+; CHECK-SPIRV: %[[#Func]] = OpFunction %[[#VoidTy]] None %[[#]]
+; CHECK-SPIRV: %[[#ConvertId1:]] = OpUConvert %[[#CharTy]] %[[#]]
+; CHECK-SPIRV: %[[#ConvertId2:]] = OpConvertSToF %[[#FloatTy]] %[[#]]
+; CHECK-SPIRV: %[[#]] = OpFunctionCall %[[#VoidTy]] %[[#Func]] %[[#ConvertId2]]
+; CHECK-SPIRV: %[[#]] = OpFunctionCall %[[#VoidTy]] %[[#Func1]] %[[#]]
+; CHECK-SPIRV: %[[#]] = OpFunctionCall %[[#VoidTy]] %[[#Func2]] %[[#ConvertId2]]
+; CHECK-SPIRV-NOT: OpFConvert
+; CHECK-SPIRV-NOT: OpConvertUToF
+
+define dso_local spir_func void @_Z18convert_float_func(float noundef %x) {
+entry:
+  %x.addr = alloca float, align 4
+  store float %x, ptr %x.addr, align 4
+  ret void
+}
+
+define dso_local spir_func void @_Z20convert_uint_satfunc(i32 noundef %x) {
+entry:
+  ret void
+}
+
+define dso_local spir_func void @_Z21convert_float_rtzfunc(float noundef %x) {
+entry:
+  ret void
+}
+
+define dso_local spir_func void @convert_int_bf16(i32 noundef %x) {
+entry:
+  %x.addr = alloca i32, align 4
+  store i32 %x, ptr %x.addr, align 4
+  %0 = load i32, ptr %x.addr, align 4
+  call spir_func signext i8 @_Z16convert_char_rtei(i32 noundef %0)
+  %call = call spir_func float @_Z13convert_floati(i32 noundef %0)
+  call spir_func void @_Z18convert_float_func(float noundef %call)
+  call spir_func void @_Z20convert_uint_satfunc(i32 noundef %0)
+  call spir_func void @_Z21convert_float_rtzfunc(float noundef %call)
+  ret void
+}
+
+declare spir_func signext i8 @_Z16convert_char_rtei(i32 noundef)
+
+declare spir_func float @_Z13convert_floati(i32 noundef)
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/nan.ll b/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/nan.ll
new file mode 100644
index 0000000000000..1072f073924be
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/nan.ll
@@ -0,0 +1,15 @@
+; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; Check OpenCL built-in nan translation.
+
+; CHECK-SPIRV: %[[#]] = OpExtInst %[[#]] %[[#]] nan %[[#]]
+
+define dso_local spir_kernel void @test(ptr addrspace(1) align 4 %a, i32 %b) {
+entry:
+  %call = tail call spir_func float @_Z3nanj(i32 %b)
+  store float %call, ptr addrspace(1) %a, align 4
+  ret void
+}
+
+declare spir_func float @_Z3nanj(i32)
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/shuffle.ll b/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/shuffle.ll
new file mode 100644
index 0000000000000..aeca431f89e20
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/shuffle.ll
@@ -0,0 +1,23 @@
+; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; Check OpenCL built-in shuffle and shuffle2 translation.
+
+; CHECK-SPIRV: %[[#]] = OpExtInst %[[#]] %[[#]] shuffle %[[#]] %[[#]]
+; CHECK-SPIRV: %[[#]] = OpExtInst %[[#]] %[[#]] shuffle2 %[[#]] %[[#]] %[[#]]
+
+define spir_kernel void @test() {
+entry:
+  %call = call spir_func <2 x float> @_Z7shuffleDv2_fDv2_j(<2 x float> zeroinitializer, <2 x i32> zeroinitializer)
+  ret void
+}
+
+declare spir_func <2 x float> @_Z7shuffleDv2_fDv2_j(<2 x float>, <2 x i32>)
+
+define spir_kernel void @test2() {
+entry:
+  %call = call spir_func <4 x float> @_Z8shuffle2Dv2_fS_Dv4_j(<2 x float> zeroinitializer, <2 x float> zeroinitializer, <4 x i32> zeroinitializer)
+  ret void
+}
+
+declare spir_func <4 x float> @_Z8shuffle2Dv2_fS_Dv4_j(<2 x float>, <2 x float>, <4 x i32>)
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/printf.ll b/llvm/test/CodeGen/SPIRV/transcoding/printf.ll
new file mode 100644
index 0000000000000..338f0a52248e5
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/transcoding/printf.ll
@@ -0,0 +1,14 @@
+; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+@.str = private unnamed_addr addrspace(2) constant [12 x i8] c"Hello World\00", align 1
+
+; CHECK-SPIRV: %[[#]] = OpExtInst %[[#]] %[[#]] printf %[[#]]
+
+define dso_local spir_kernel void @BuiltinPrintf() {
+entry:
+  %call = tail call i32 (ptr addrspace(2), ...) @printf(ptr addrspace(2) noundef @.str)
+  ret void
+}
+
+declare noundef i32 @printf(ptr addrspace(2) nocapture noundef readonly, ...)

@michalpaszkowski michalpaszkowski merged commit 09a6a25 into llvm:main Aug 3, 2025
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants